package com.xtm.exercise.base;

import org.junit.Test;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;

/*
static 表示的概念是 静态的，在 Java 中，static 主要用来：

修饰变量，static 修饰的变量称为静态变量、也称为类变量，类变量属于类所有，对于不同的类来说，static 变量只有一份，
static 修饰的变量位于方法区中；static 修饰的变量能够直接通过 类名.变量名 来进行访问，不用通过实例化类再进行使用。
修饰方法，static 修饰的方法被称为静态方法，静态方法能够直接通过 类名.方法名 来使用，在静态方法内部不能使用非静态属性和方法
static 可以修饰代码块，主要分为两种，一种直接定义在类中，使用 static{}，这种被称为静态代码块，一种是在类中定义静态内部类，使用 static class xxx 来进行定义。
static 可以用于静态导包，通过使用 import static xxx 来实现，这种方式一般不推荐使用
static 可以和单例模式一起使用，通过双重检查锁来实现线程安全的单例模式。

    static关键字
         静态的特点
             随着类的加载而加载
                 优先于对象存在
                 对所有对象共享
                 可以被类型直接调用
         静态的注意事项
             在静态方法中不能使用this，super关键字
             由于jvm调用main方法的时候，没有创建对象，只能通过类名调用，所以main必须用static修饰
             main方法是被jvm调用，不需要返回值，用void修饰
         静态变量和成员变量的区别
             调用方式
                 静态变量也称为类变量，可以直接通过类名调用，也可以通过对象名调用这个变量属于类
                 成员变量也称为实例变量，只能通过对象名调用，这个变量属于对象
             存储位置
                 静态变量存储在方法区长中的静态区
                 成员变量存储在堆内存
             声明周期
                 静态变量随着类的加载而存在，随着类的消失而消失，生命周期长
                 成员变量随着对象的创建而存在，随着对象的消失而消失
             与对象的相关性
                 静态变量是所有对象共享的数据
                 成员变量是每个对象所特有的数据
             静态的优点和弊端
                 优点
                      对对象的共享数据进行单独空间的存储，节省内存，没有必要每个对象都存储一份可直接被类名调用
                 弊端
                      生命周期过长，随着类的消失而消失
                      访问出现权限，即静态虽好但只能访问静态
             什么时候使用静态呢
                 当所有对象共享某个数据的时候，就把这个成员变量定义为静态修饰的
                 当某个方法没有访问该类中的非静态成员，就可以把这个方法定义为静态修饰，静态的生命周期比较长吗，所以一般不推荐使用
             静态代码块
                 它只执行一次，它比mian还先执行
                 执行顺序：静态代码块--构造代码块--构造方法
 */
@Component
public class Z02StaticDemo {
    /**
     * 1.静态代码块
     * 2.静态变量
     * 3.静态方法
     * 4.静态常量
     */
    /*
       静态常量
            格式：
            public static final 数据类型 常量名称 = 数据值;
            备注：
            一旦使用final关键字进行修饰，说明不可改变。这其实就是一个常量，一旦赋值，不可以修改
    */
    public static final int NUM_OF_MY_CLASS = 12;

    //静态变量相当于内存，用来传输数据  这是全局的静态变量
    public static ConcurrentLinkedQueue applyInsertCache = new ConcurrentLinkedQueue();
    public static ConcurrentLinkedQueue applyDeleteCache = new ConcurrentLinkedQueue();
    public static ConcurrentHashMap applyQueryCache = new ConcurrentHashMap();

    //静态变量
    public static String name = "wl";
    //静态方法
    public static void test03(){
        System.out.println("执行静态方法 test01");
    }
    /*
        静态代码块，在JVM虚拟机加载类的时候就会加载执行，而且只执行一次;
        特点：在这个类第一次被调用或实例化的时候就会被执行，静态代码块执行唯一的一次，一般会用来初始化一些值，并且在所有对象中全局共享。
        静态代码块的典型用途：
            用来一次性地对静态成员变量进行赋值
        非静态代码块，在创建对象的时候(即new一个对象的时候)执行，每次创建对象都会执行一次
    */
    static{
        System.out.println("This is static block.");
        int stVar = 0;   //这是一个局部变量，只在本块内有效
    }

    //运行main方法  执行静态代码块的内容
    public static void main(String[] args) {

    }

    @Test
    public void test01(){
        applyInsertCache.poll();
        Map map = new HashMap();
        applyInsertCache.offer(map);

    }
    @Test
    public void test02(){
        //调用静态变量
        System.out.println("调用静态变量"+name);

        //调用静态方法  类名.方法名
        Z02StaticDemo.test03();

    }

}
